// $codepro.audit.disable
package edu.gatech.teama.doctorsoffice.test;

import org.joda.time.LocalDate;
import org.joda.time.LocalDateTime;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import edu.gatech.teama.doctorsoffice.server.*;
import edu.gatech.teama.doctorsoffice.model.Address;
import edu.gatech.teama.doctorsoffice.model.Gender;
import edu.gatech.teama.doctorsoffice.model.Patient;
import edu.gatech.teama.doctorsoffice.model.User;
import edu.gatech.teama.doctorsoffice.net.*;

import java.io.File;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


public class M7TestStephen {
	private Server srv;
	Socket clientSocket;
	ObjectOutputStream out
;
	ObjectInputStream in
;
	ExecutorService pool;
	final String testDataFileName = "test.dat";
	User testUser;
	public void startServer() {
		try {
			// Execute server on new thread
			srv = new Server(4123, testDataFileName);
			pool = Executors.newSingleThreadExecutor();
			pool.execute(srv);

			// Give the server some time to start
			Thread.sleep(100);

			clientSocket = new Socket("localhost", 4123);

			out = new ObjectOutputStream(clientSocket.getOutputStream());
			out.flush();
			in = new ObjectInputStream(clientSocket.getInputStream());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

//	@Before
//	public void setUp() throws Exception {
//		// Delete data file if a previous one exists
//		Address patientAddress=new Address(123, "Fake St", 30332, "Atlanta", "Georgia");
//		LocalDate dob = new LocalDate();
//		testUser= new Patient("uSeR1","JohnFirst","JohnLast", "404-404-4040", patientAddress,"a@gatech.edu", 
//				Gender.MALE,dob, "CVS", "BCBS");
//		File f = new File(testDataFileName);
//		if (f.exists()) {
//			f.delete();
//		}
//
//		startServer();
//	}

	@After
	public void tearDown() throws Exception {
		out.writeObject(new QuitMessage());
		clientSocket.close();
		pool.shutdownNow();
	}

	@Test
	public void testLookupPatientByName1(){

		try {
			out.writeObject(new AddUserMessage(testUser, "abc123"));
			Message mess = (Message)in.readUnshared();
			Assert.assertTrue((Boolean)mess.getPayload());

			out.writeObject(new LookupPatientMessage(testUser.getFirstName(),testUser.getLastName()));
			mess=(Message)in.readUnshared();
			User resultUser=((ArrayList<Patient>)mess.getPayload()).get(0);
			Assert.assertTrue((resultUser.getFirstName()).equals(testUser.getFirstName()));
			Assert.assertTrue((resultUser.getLastName()).equals(testUser.getLastName()));

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			Assert.fail();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			Assert.fail();
		}
	}
	
	@Test
	public void testLookupPatientByName2(){

		try {
			out.writeObject(new AddUserMessage(testUser, "abc123"));
			Message mess = (Message)in.readUnshared();
			Assert.assertTrue((Boolean)mess.getPayload());


			out.writeObject(new LookupPatientMessage("notFirstName",testUser.getLastName()));
			mess = (Message)in.readUnshared();
			Assert.assertEquals(0, ((List<Patient>)mess.getPayload()).size());
			//Assert.assertNull((Message)in.readUnshared());
			//resultUser=(Patient)mess.getPayload();
			//Assert.assertFalse((resultUser.getFirstName()).equals(testUser.getFirstName()));
			//Assert.assertFalse((resultUser.getLastName()).equals(User.getLastName()));


		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			Assert.fail();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
	
		Assert.fail();
		}
	}
	@Test
	public void testLookupPatientByName3(){

		try {
			out.writeObject(new AddUserMessage(testUser, "abc123"));
			Message mess = (Message)in.readUnshared();
			Assert.assertTrue((Boolean)mess.getPayload());

			out.writeObject(new LookupPatientMessage(testUser.getFirstName(),"notLastName"));
			Assert.assertNull((Message)in.readUnshared());
			mess = (Message)in.readUnshared();
			User resultUser=(Patient)mess.getPayload();
			Assert.assertFalse((resultUser.getFirstName()).equals(testUser.getFirstName()));
			Assert.assertFalse((resultUser.getLastName()).equals(testUser.getLastName()));

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			Assert.fail();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
	
		Assert.fail();
		}
	}
	@Test
	public void testLookupPatientByName4(){

		try {
			out.writeObject(new AddUserMessage(testUser, "abc123"));
			Message mess = (Message)in.readUnshared();
			Assert.assertTrue((Boolean)mess.getPayload());

			out.writeObject(new LookupPatientMessage(testUser.getFirstName(),testUser.getLastName().toLowerCase()));
			mess = (Message)in.readUnshared();
			User resultUser=((ArrayList<Patient>)mess.getPayload()).get(0);
			Assert.assertTrue((resultUser.getFirstName()).equals(testUser.getFirstName()));
			Assert.assertTrue((resultUser.getLastName()).equals(testUser.getLastName()));

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			Assert.fail();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			Assert.fail();
		}
	}
	
}

